package com.app.ui;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.ArrayList;
import java.util.List;

public class LogFileReader {

  /**
   * 从指定位置开始读取文件的新内容
   * 
   * @param file          要读取的文件
   * @param startPosition 开始读取的位置
   * @return 从指定位置开始的新内容
   * @throws IOException 如果读取文件时出错
   */
  public String readNewContent(File file, long startPosition) throws IOException {
    StringBuilder content = new StringBuilder();

    if (!file.exists()) {
      throw new IOException("文件不存在: " + file.getPath());
    }

    // 首先尝试使用多种方法读取文件
    // 方法1: 使用FileInputStream和InputStreamReader
    try {
      System.out.println("尝试使用FileInputStream读取文件...");
      try (FileInputStream fis = new FileInputStream(file);
          BufferedReader reader = new BufferedReader(new InputStreamReader(fis, StandardCharsets.UTF_8))) {

        // 跳过已读取的部分
        if (startPosition > 0) {
          reader.skip(startPosition);
        }

        String line;
        while ((line = reader.readLine()) != null) {
          content.append(line).append("\n");
        }

        if (content.length() > 0) {
          System.out.println("使用FileInputStream成功读取文件内容");
          return content.toString();
        }
      } catch (Exception e) {
        System.out.println("FileInputStream读取失败: " + e.getMessage());
      }

      // 方法2: 如果方法1失败，尝试使用RandomAccessFile
      System.out.println("尝试使用RandomAccessFile读取文件...");
      content.setLength(0); // 清空StringBuilder

      try (RandomAccessFile raf = new RandomAccessFile(file, "r")) {
        // 将文件指针移动到起始位置
        if (startPosition > 0 && startPosition < file.length()) {
          raf.seek(startPosition);
        }

        String line;
        while ((line = raf.readLine()) != null) {
          // 尝试不同的编码
          try {
            line = new String(line.getBytes("ISO-8859-1"), StandardCharsets.UTF_8);
          } catch (Exception e) {
            // 如果转换失败，保持原样
          }
          content.append(line).append("\n");
        }

        if (content.length() > 0) {
          System.out.println("使用RandomAccessFile成功读取文件内容");
          return content.toString();
        }
      } catch (Exception e) {
        System.out.println("RandomAccessFile读取失败: " + e.getMessage());
      }

      // 方法3: 如果前两种方法都失败，尝试使用Files API
      System.out.println("尝试使用Files API读取文件...");
      content.setLength(0); // 清空StringBuilder

      List<String> allLines = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
      for (String line : allLines) {
        content.append(line).append("\n");
      }

      System.out.println("使用Files API成功读取文件内容");
      return content.toString();

    } catch (Exception e) {
      throw new IOException("所有读取方法都失败: " + e.getMessage(), e);
    }
  }

  /**
   * 读取文件的指定行数
   * 
   * @param file          要读取的文件
   * @param startPosition 开始读取的位置
   * @param maxLines      最大行数
   * @return 读取的内容和新的文件位置
   * @throws IOException 如果读取文件时出错
   */
  public FileReadResult readLines(File file, long startPosition, int maxLines) throws IOException {
    if (!file.exists()) {
      throw new IOException("文件不存在: " + file.getPath());
    }

    List<String> lines = new ArrayList<>();
    long newPosition = startPosition;

    try (RandomAccessFile raf = new RandomAccessFile(file, "r")) {
      // 将文件指针移动到起始位置
      if (startPosition > 0 && startPosition < file.length()) {
        raf.seek(startPosition);
      } else if (startPosition >= file.length()) {
        // 如果指定的位置超过了文件长度，则返回空结果
        return new FileReadResult(lines, startPosition);
      }

      String line;
      int lineCount = 0;

      while (lineCount < maxLines && (line = raf.readLine()) != null) {
        // 将ISO-8859-1编码的行转换为UTF-8编码
        byte[] bytes = line.getBytes("ISO-8859-1");
        line = new String(bytes, StandardCharsets.UTF_8);
        lines.add(line);
        lineCount++;

        // 更新新的位置
        newPosition = raf.getFilePointer();
      }
    }

    return new FileReadResult(lines, newPosition);
  }

  /**
   * 获取文件的当前大小
   * 
   * @param file 文件
   * @return 文件大小，以字节为单位
   */
  public long getFileSize(File file) {
    return file.length();
  }

  /**
   * 检查文件是否被修改
   * 
   * @param file         要检查的文件
   * @param lastModified 上次修改的时间戳
   * @return 如果文件被修改则返回true，否则返回false
   */
  public boolean hasFileChanged(File file, long lastModified) {
    return file.lastModified() > lastModified;
  }

  /**
   * 直接打印文件内容（用于调试）
   * 
   * @param file 要读取的文件
   * @throws IOException 如果读取文件时出错
   */
  public void printFileContent(File file) throws IOException {
    System.out.println("尝试读取文件: " + file.getAbsolutePath());
    System.out.println("文件大小: " + file.length() + " 字节");

    try (FileInputStream fis = new FileInputStream(file);
        InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8);
        BufferedReader reader = new BufferedReader(isr)) {

      String line;
      System.out.println("文件内容：");
      while ((line = reader.readLine()) != null) {
        System.out.println(line);
      }
    }
  }

  /**
   * 表示文件读取结果的类
   */
  public static class FileReadResult {
    private final List<String> lines;
    private final long newPosition;

    public FileReadResult(List<String> lines, long newPosition) {
      this.lines = lines;
      this.newPosition = newPosition;
    }

    public List<String> getLines() {
      return lines;
    }

    public long getNewPosition() {
      return newPosition;
    }

    public boolean hasContent() {
      return !lines.isEmpty();
    }
  }
}